﻿using System.Data;
using RpcHelper;
using SqlExecHelper.Cache;
using SqlExecHelper.Config;
using SqlExecHelper.Drop;
using SqlExecHelper.Insert;
using SqlExecHelper.Interface;
using SqlExecHelper.Join;
using SqlExecHelper.Merge;
using SqlExecHelper.Query;
using SqlExecHelper.SqlValue;
using SqlExecHelper.TempTable;
using SqlExecHelper.Update;

namespace SqlExecHelper
{
    public class SqlExecTool
    {
        public static IBatchMerge BatchMerge(string table, IDAL dal, int row, int col)
        {
            if (row > SqlConfig.TempTableLimitNum || (row * col) > SqlConfig.MxColumnNum)
            {
                return new TempTableMerge(table, dal);
            }
            else
            {
                return new BatchMerge(table, dal);
            }
        }

        #region 连表查询
        public static T JoinScalar<T>(string one, string two, IDAL dal, string column, SqlFuncType funcType, params ISqlWhere[] where)
        {
            JoinTable[] tables = new JoinTable[]
            {
                                new JoinTable(two,"b",SqlConfig.QueryLockType)
            };
            ISqlBasic query = new SqlJoinQuery(one, SqlConfig.QueryLockType, tables, new JoinColumn
            {
                Column = column,
                Table = one,
                FuncType = funcType,
            }, where);
            return SqlHelper.ExecuteScalar<T>(query, dal);
        }
        public static T[] JoinQuery<T>(string one, string two, IDAL dal, params ISqlWhere[] where)
        {
            JoinTable[] tables = new JoinTable[]
            {
                                new JoinTable(two,"b",SqlConfig.QueryLockType)
            };
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic query = new SqlJoinQuery(one, SqlConfig.QueryLockType, tables, obj, where);
            return SqlHelper.GetTable<T>(query, dal);
        }
        public static T[] JoinQuery<T>(string one, string two, IDAL dal, JoinColumn column, params ISqlWhere[] where)
        {
            JoinTable[] tables = new JoinTable[]
            {
                                new JoinTable(two,"b",SqlConfig.QueryLockType)
            };
            ISqlBasic query = new SqlJoinQuery(one, SqlConfig.QueryLockType, tables, column, where);
            return SqlHelper.GetTable<T>(query, dal);
        }
        public static T[] JoinQuery<T>(string one, string two, IDAL dal, IOrderBy[] orderby, params ISqlWhere[] where)
        {
            JoinTable[] tables = new JoinTable[]
            {
                                new JoinTable(two,"b",SqlConfig.QueryLockType)
            };
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic query = new SqlJoinQuery(one, SqlConfig.QueryLockType, tables, obj, orderby, where);
            return SqlHelper.GetTable<T>(query, dal);
        }
        public static T[] JoinQuery<T>(string one, string two, IDAL dal, IOrderBy[] orderBy, int index, int size, out long count, params ISqlWhere[] where)
        {
            JoinTable[] tables = new JoinTable[]
            {
                                new JoinTable(two,"b",SqlConfig.QueryLockType)
            };
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic query = new SqlJoinPagingQuery(one, SqlConfig.QueryLockType, index, size, tables, obj, orderBy, where);
            return SqlHelper.Query<T>(query, dal, out count);
        }

        public static T[] JoinQuery<T>(string one, string two, IDAL dal, IOrderBy[] orderBy, int index, int size, JoinColumn column, params ISqlWhere[] where)
        {
            JoinTable[] tables = new JoinTable[]
            {
                                new JoinTable(two,"b",SqlConfig.QueryLockType)
            };
            ISqlBasic query = new SqlJoinPagingQuery(one, SqlConfig.QueryLockType, index, size, true, tables, column, orderBy, where);
            return SqlHelper.GetTable<T>(query, dal);
        }
        public static T[] JoinQuery<T>(string one, string two, IDAL dal, IOrderBy[] orderBy, int index, int size, params ISqlWhere[] where)
        {
            JoinTable[] tables = new JoinTable[]
            {
                                new JoinTable(two,"b",SqlConfig.QueryLockType)
            };
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic query = new SqlJoinPagingQuery(one, SqlConfig.QueryLockType, index, size, true, tables, obj, orderBy, where);
            return SqlHelper.GetTable<T>(query, dal);
        }
        #endregion

        #region "插入"

        public static IInsertTable InsertTable(string tableName, IDAL dal, int row, int col)
        {
            if (row > SqlConfig.TempTableLimitNum || (row * col) > SqlConfig.MxColumnNum)
            {
                return new InsertTable(tableName, dal);
            }
            else
            {
                return new BatchInsert(tableName, dal);
            }
        }
        public static IBatchInsert BatchInsert(string tableName, IDAL dal)
        {
            return new BatchInsert(tableName, dal);
        }
        public static IInsertTable InsertTable(string tableName, IDAL dal)
        {
            return new InsertTable(tableName, dal);
        }
        public static void Insert<T>(string tableName, IDAL dal, T[] adds) where T : class
        {
            if (adds.Length == 1)
            {
                Insert(tableName, dal, adds[0]);
                return;
            }
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            TableColumn[] cols = obj.GetTableColumn();
            IInsertTable table = InsertTable(tableName, dal, adds.Length, cols.Length);
            table.Column = cols;
            adds.ForEach(a => table.AddRow(obj.GetRow(a)));
            table.Save();
        }
        public static Result[] Insert<T, Result>(string tableName, IDAL dal, T[] adds) where T : class
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            IBatchInsert table = BatchInsert(tableName, dal);
            table.Column = obj.GetTableColumn();
            adds.ForEach(a => table.AddRow(obj.GetRow(a)));
            return table.Save<Result>();
        }
        public static Result[] InsertOutColumn<T, Result>(string tableName, IDAL dal, T[] adds, string column) where T : class
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            IBatchInsert table = BatchInsert(tableName, dal);
            table.Column = obj.GetTableColumn();
            adds.ForEach(a => table.AddRow(obj.GetRow(a)));
            return table.Save<Result>(column);
        }
        public static void Insert<T>(string tableName, IDAL dal, T data) where T : class
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic insert = new SqlInsert(obj, tableName, data);
            _ = SqlHelper.ExecuteNonQuery(insert, dal);
        }
        public static Result InsertOutRow<T, Result>(string tableName, IDAL dal, T data) where T : class
        {
            ClassStructure res = ClassStructureCache.GetStructure(typeof(Result));
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic insert = new SqlInsertOut(obj, tableName, data, res);
            return SqlHelper.GetRow<Result>(insert, dal);
        }
        public static Result InsertOutColumn<T, Result>(string tableName, IDAL dal, T data, string column) where T : class
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic insert = new SqlInsertOut(obj, tableName, data, column);
            return SqlHelper.ExecuteScalar<Result>(insert, dal);
        }
        public static void Insert<T>(string tableName, IDAL dal, T data, out long id) where T : class
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic insert = new SqlInsertById(obj, tableName, data, SqlDbType.BigInt);
            SqlHelper.Insert(insert, dal, out id);
        }
        public static void Insert(string tableName, IDAL dal, IInsertSqlValue[] column, out long id)
        {
            ISqlBasic insert = new SqlInsertById(column, tableName, SqlDbType.BigInt);
            SqlHelper.Insert(insert, dal, out id);
        }
        public static void Insert(string tableName, IDAL dal, IInsertSqlValue[] column, out int id)
        {
            ISqlBasic insert = new SqlInsertById(column, tableName, SqlDbType.BigInt);
            SqlHelper.Insert(insert, dal, out id);
        }
        public static void Insert<T>(string tableName, IDAL dal, T data, out int id) where T : class
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic insert = new SqlInsertById(obj, tableName, data, SqlDbType.BigInt);
            SqlHelper.Insert(insert, dal, out id);
        }
        #endregion

        #region 删除数据

        public static IBatchDrop BatchDrop(string tableName, IDAL dal, int row, int col)
        {
            if (row > SqlConfig.TempTableLimitNum || (row * col) > SqlConfig.MxColumnNum)
            {
                return new TempTableDrop(tableName, SqlConfig.DropLockType, dal);
            }
            return new BatchDrop(tableName, SqlConfig.DropLockType, dal);
        }
        public static bool BatchDrop<T>(string tableName, IDAL dal, string column, T[] datas, params ISqlWhere[] param)
        {
            using (IBatchDrop drop = BatchDrop(tableName, dal, datas.Length, 1))
            {
                drop.Column = new SqlTableColumn[]
                {
                                        new SqlTableColumn(column,SqlToolsHelper.GetSqlDbType(typeof(T)))
                };
                datas.ForEach(a => drop.AddRow(new object[] { a }));
                return drop.Drop(param);
            }
        }
        public static Result[] BatchDrop<T, Result>(string tableName, IDAL dal, string column, T[] datas, params ISqlWhere[] param)
        {
            using (IBatchDrop drop = BatchDrop(tableName, dal, datas.Length, 1))
            {
                drop.Column = new SqlTableColumn[]
                {
                                        new SqlTableColumn(column,SqlToolsHelper.GetSqlDbType(typeof(T)))
                };
                datas.ForEach(a => drop.AddRow(new object[] { a }));
                return drop.Drop<Result>(param);
            }
        }
        public static Result[] BatchDrop<T, Result>(string tableName, IDAL dal, string column, T[] datas, string returnCol, params ISqlWhere[] param)
        {
            using (IBatchDrop drop = BatchDrop(tableName, dal, datas.Length, 1))
            {
                drop.Column = new SqlTableColumn[]
                {
                                        new SqlTableColumn(column,SqlToolsHelper.GetSqlDbType(typeof(T)))
                };
                datas.ForEach(a => drop.AddRow(new object[] { a }));
                return drop.Drop<Result>(returnCol, param);
            }
        }
        public static bool Drop(string tableName, IDAL dal, ISqlWhere[] where)
        {
            ISqlBasic drop = new SqlDrop(tableName, SqlConfig.DropLockType, where);
            return SqlHelper.ExecuteNonQuery(drop, dal) > 0;
        }
        public static bool Drop<T>(string tableName, IDAL dal, string column, T data)
        {
            ISqlWhere where = new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(T))) { Value = data };
            ISqlBasic drop = new SqlDrop(tableName, SqlConfig.DropLockType, where);
            return SqlHelper.ExecuteNonQuery(drop, dal) > 0;
        }
        public static bool Drop<T>(string tableName, IDAL dal, string column, T data, ISqlWhere[] where)
        {
            ISqlWhere add = new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(T))) { Value = data };
            ISqlWhere[] wheres = where == null ? new ISqlWhere[] {
                                add
                        } : where.Add(add);
            ISqlBasic drop = new SqlDrop(tableName, SqlConfig.DropLockType, wheres);
            return SqlHelper.ExecuteNonQuery(drop, dal) > 0;
        }
        public static Result DropOutRow<T, Result>(string tableName, IDAL dal, string column, T data)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(Result));
            ISqlWhere where = new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(T))) { Value = data };
            ISqlBasic drop = new SqlDropOut(tableName, SqlConfig.DropLockType, obj, where);
            return SqlHelper.GetRow<Result>(drop, dal);
        }
        public static Result DropOutScalar<T, Result>(string tableName, IDAL dal, string column, T data, string returnColumn)
        {
            ISqlWhere where = new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(T))) { Value = data };
            ISqlBasic drop = new SqlDropOut(tableName, SqlConfig.DropLockType, returnColumn, where);
            return SqlHelper.ExecuteScalar<Result>(drop, dal);
        }
        public static Result[] Drop<T, Result>(string tableName, IDAL dal, string column, T data, string returnColumn)
        {
            ISqlWhere where = new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(T))) { Value = data };
            ISqlBasic drop = new SqlDropOut(tableName, SqlConfig.DropLockType, returnColumn, where);
            return SqlHelper.GetTable<Result>(drop, dal);
        }
        public static T DropOutRow<T>(string tableName, IDAL dal, ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic drop = new SqlDropOut(tableName, SqlConfig.DropLockType, obj, where);
            return SqlHelper.GetRow<T>(drop, dal);
        }
        public static T[] Drop<T>(string tableName, IDAL dal, ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic drop = new SqlDropOut(tableName, SqlConfig.DropLockType, obj, where);
            return SqlHelper.GetTable<T>(drop, dal);
        }
        public static T DropOutScalar<T>(string tableName, IDAL dal, string column, ISqlWhere[] where)
        {
            ISqlBasic drop = new SqlDropOut(tableName, SqlConfig.DropLockType, column, where);
            return SqlHelper.ExecuteScalar<T>(drop, dal);
        }
        public static T[] DropOutColumn<T>(string tableName, IDAL dal, string column, ISqlWhere[] where)
        {
            ISqlBasic drop = new SqlDropOut(tableName, SqlConfig.DropLockType, column, where);
            return SqlHelper.GetTable<T>(drop, dal);
        }
        #endregion

        #region 修改


        public static IBatchUpdate BatchUpdate(string tableName, IDAL dal, int row, int col)
        {
            if (row > SqlConfig.TempTableLimitNum || (row * col) > SqlConfig.MxColumnNum)
            {
                return new TempTableUpdate(tableName, SqlConfig.SetLockType, dal);
            }
            return new BatchUpdate(tableName, SqlConfig.DropLockType, dal);
        }

        public static bool Update(string tableName, IDAL dal, ISqlSetColumn[] columns, params ISqlWhere[] where)
        {
            ISqlBasic update = new SqlUpdate(tableName, SqlConfig.SetLockType, columns, where);
            return SqlHelper.ExecuteNonQuery(update, dal) > 0;
        }
        public static bool Update(string one, string two, IDAL dal, ISqlSetColumn[] columns, params ISqlWhere[] where)
        {
            ISqlBasic sql = new SqlJoinUpdate(one, two, SqlConfig.SetLockType, SqlConfig.QueryLockType, columns, where);
            return SqlHelper.ExecuteNonQuery(sql, dal) != -2;
        }
        public static bool Update<T, Val>(string tableName, IDAL dal, T data, string column, Val[] vals, params ISqlWhere[] where)
        {
            ISqlSetColumn[] cols = ClassStructureCache.GetStructure(typeof(T)).GetUpdateColumn(data);
            if (vals.Length == 1)
            {
                where = where.TopInsert(new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(Val))) { Value = vals[0] });
                return Update(tableName, dal, cols, where);
            }
            else if (vals.Length <= SqlConfig.InMaxNum)
            {
                where = where.TopInsert(new InSqlWhere<Val>(column, SqlToolsHelper.GetSqlDbType(typeof(Val)), vals));
                return Update(tableName, dal, cols, where);
            }
            else
            {
                using (IBatchUpdate batch = BatchUpdate(tableName, dal, vals.Length, 1))
                {
                    batch.Column = new SqlTableColumn[]
                    {
                                                new SqlTableColumn(column, SqlToolsHelper.GetSqlDbType(typeof(Val))){ ColType= SqlColType.查询}
                    };
                    vals.ForEach(a => batch.AddRow(a));
                    return batch.Update(cols, where);
                }
            }
        }
        public static bool Update<T>(string tableName, IDAL dal, ISqlSetColumn[] columns, string column, T[] vals, params ISqlWhere[] where)
        {
            if (vals.Length == 1)
            {
                where = where.TopInsert(new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(T))) { Value = vals[0] });
                return Update(tableName, dal, columns, where);
            }
            else if (vals.Length <= SqlConfig.InMaxNum)
            {
                where = where.TopInsert(new InSqlWhere<T>(column, SqlToolsHelper.GetSqlDbType(typeof(T)), vals));
                return Update(tableName, dal, columns, where);
            }
            else
            {
                using (IBatchUpdate batch = BatchUpdate(tableName, dal, vals.Length, 1))
                {
                    batch.Column = new SqlTableColumn[]
                    {
                                     new SqlTableColumn(column, SqlToolsHelper.GetSqlDbType(typeof(T))){ ColType= SqlColType.查询}
                    };
                    vals.ForEach(a => batch.AddRow(a));
                    return batch.Update(columns, where);
                }
            }
        }
        public static Result[] Update<T, Result>(string tableName, IDAL dal, ISqlSetColumn[] columns, SqlEventPrefix prefix, string column, T[] vals, params ISqlWhere[] where)
        {
            if (vals.Length == 1)
            {
                where = where.TopInsert(new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(T))) { Value = vals[0] });
                return Update<Result>(tableName, dal, columns, prefix, where);
            }
            else if (vals.Length <= SqlConfig.InMaxNum)
            {
                where = where.TopInsert(new InSqlWhere<T>(column, SqlToolsHelper.GetSqlDbType(typeof(T)), vals));
                return Update<Result>(tableName, dal, columns, prefix, where);
            }
            else
            {
                using (IBatchUpdate batch = BatchUpdate(tableName, dal, vals.Length, 1))
                {
                    batch.Column = new SqlTableColumn[]
                    {
                                                new SqlTableColumn(column, SqlToolsHelper.GetSqlDbType(typeof(T))){ ColType= SqlColType.查询}
                    };
                    vals.ForEach(a => batch.AddRow(a));
                    return batch.Update<Result>(columns, prefix, where);
                }
            }
        }
        public static Result[] Update<T, Result>(string tableName, IDAL dal, ISqlSetColumn[] columns, string rcolumn, SqlEventPrefix prefix, string column, T[] vals, params ISqlWhere[] where)
        {
            if (vals.Length == 1)
            {
                where = where.TopInsert(new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(T))) { Value = vals[0] });
                return Update<Result>(tableName, dal, columns, rcolumn, prefix, where);
            }
            else if (vals.Length <= SqlConfig.InMaxNum)
            {
                where = where.TopInsert(new InSqlWhere<T>(column, SqlToolsHelper.GetSqlDbType(typeof(T)), vals));
                return Update<Result>(tableName, dal, columns, rcolumn, prefix, where);
            }
            else
            {
                using (IBatchUpdate batch = BatchUpdate(tableName, dal, vals.Length, 1))
                {
                    batch.Column = new SqlTableColumn[]
                    {
                         new SqlTableColumn(column, SqlToolsHelper.GetSqlDbType(typeof(T))){ ColType= SqlColType.查询}
                    };
                    vals.ForEach(a => batch.AddRow(a));
                    return batch.Update<Result>(columns, rcolumn, prefix, where);
                }
            }
        }
        public static Result[] Update<T, Result>(string tableName, IDAL dal, ISqlSetColumn[] columns, string column, T[] vals, string retCol, SqlEventPrefix prefix, params ISqlWhere[] where)
        {
            if (vals.Length == 1)
            {
                where = where.TopInsert(new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(T))) { Value = vals[0] });
                return Update<Result>(tableName, dal, columns, retCol, prefix, where);
            }
            else if (vals.Length <= SqlConfig.InMaxNum)
            {
                where = where.TopInsert(new InSqlWhere<T>(column, SqlToolsHelper.GetSqlDbType(typeof(T)), vals));
                return Update<Result>(tableName, dal, columns, retCol, prefix, where);
            }
            else
            {
                using (IBatchUpdate batch = BatchUpdate(tableName, dal, vals.Length, 1))
                {
                    batch.Column = new SqlTableColumn[]
                    {
                        new SqlTableColumn(column, SqlToolsHelper.GetSqlDbType(typeof(T))){ ColType= SqlColType.查询}
                    };
                    vals.ForEach(a => batch.AddRow(a));
                    return batch.Update<Result>(retCol, prefix, columns, where);
                }
            }
        }

        public static bool Update<T>(string tableName, IDAL dal, ISqlSetColumn[] columns, string column, T val)
        {
            ISqlWhere where = new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(T))) { Value = val };
            ISqlBasic update = new SqlUpdate(tableName, SqlConfig.SetLockType, columns, where);
            return SqlHelper.ExecuteNonQuery(update, dal) > 0;
        }
        public static Result UpdateOutRow<Result>(string tableName, IDAL dal, ISqlSetColumn[] columns, params ISqlWhere[] where)
        {
            ClassStructure res = ClassStructureCache.GetStructure(typeof(Result));
            ISqlBasic sql = new SqlUpdateOut(tableName, SqlConfig.SetLockType, columns, res, where);
            return SqlHelper.GetRow<Result>(sql, dal);
        }
        public static Result UpdateOutRow<Result>(string one, string two, IDAL dal, ISqlSetColumn[] columns, params ISqlWhere[] where)
        {
            ClassStructure res = ClassStructureCache.GetStructure(typeof(Result));
            ISqlBasic sql = new SqlJoinUpdateOut(one, two, Config.SqlConfig.SetLockType, SqlConfig.QueryLockType, res, SqlEventPrefix.deleted, columns, where);
            return SqlHelper.GetRow<Result>(sql, dal);
        }
        public static Result UpdateOutRow<Result>(string one, string two, IDAL dal, ISqlSetColumn[] columns, SqlEventPrefix prefix, params ISqlWhere[] where)
        {
            ClassStructure res = ClassStructureCache.GetStructure(typeof(Result));
            ISqlBasic sql = new SqlJoinUpdateOut(one, two, Config.SqlConfig.SetLockType, SqlConfig.QueryLockType, res, prefix, columns, where);
            return SqlHelper.GetRow<Result>(sql, dal);
        }
        public static Result UpdateOutRow<Result>(string tableName, IDAL dal, ISqlSetColumn[] columns, SqlEventPrefix prefix, params ISqlWhere[] where)
        {
            ClassStructure res = ClassStructureCache.GetStructure(typeof(Result));
            ISqlBasic update = new SqlUpdateOut(tableName, SqlConfig.SetLockType, columns, res, prefix, where);
            return SqlHelper.GetRow<Result>(update, dal);
        }
        public static Result UpdateOutScalar<Result>(string tableName, IDAL dal, ISqlSetColumn[] columns, string column, params ISqlWhere[] where)
        {
            ISqlBasic update = new SqlUpdateOut(tableName, SqlConfig.SetLockType, columns, column, SqlEventPrefix.deleted, where);
            return SqlHelper.ExecuteScalar<Result>(update, dal);
        }
        public static Result UpdateOutScalar<Result>(string one, string two, IDAL dal, ISqlSetColumn[] columns, string rColumn, params ISqlWhere[] where)
        {
            ISqlBasic sql = new SqlJoinUpdateOut(one, two, Config.SqlConfig.SetLockType, SqlConfig.QueryLockType, rColumn, SqlEventPrefix.deleted, columns, where);
            return SqlHelper.ExecuteScalar<Result>(sql, dal);
        }
        public static Result UpdateOutRow<Result>(string one, string two, IDAL dal, ISqlSetColumn[] columns, string column, SqlEventPrefix prefix, params ISqlWhere[] where)
        {
            ISqlBasic sql = new SqlJoinUpdateOut(one, two, Config.SqlConfig.SetLockType, SqlConfig.QueryLockType, column, prefix, columns, where);
            return SqlHelper.GetRow<Result>(sql, dal);
        }
        public static Result UpdateOutScalar<Result>(string tableName, IDAL dal, ISqlSetColumn[] columns, string column, SqlEventPrefix prefix, params ISqlWhere[] where)
        {
            ISqlBasic update = new SqlUpdateOut(tableName, SqlConfig.SetLockType, columns, column, prefix, where);
            return SqlHelper.ExecuteScalar<Result>(update, dal);
        }

        public static bool Update<T>(string tableName, IDAL dal, T data, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic update = new SqlUpdate(tableName, SqlConfig.SetLockType, obj, data, where);
            return SqlHelper.ExecuteNonQuery(update, dal) != -2;
        }
        public static bool Update<T, T1>(string tableName, IDAL dal, T data, string column, T1 val)
        {
            ISqlWhere where = new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(T1))) { Value = val };
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic update = new SqlUpdate(tableName, SqlConfig.SetLockType, obj, data, where);
            return SqlHelper.ExecuteNonQuery(update, dal) > 0;
        }


        public static Result UpdateOutRow<T, Result>(string tableName, IDAL dal, T data, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ClassStructure res = ClassStructureCache.GetStructure(typeof(Result));
            ISqlBasic update = new SqlUpdateOut(tableName, SqlConfig.SetLockType, obj, data, res, where);
            return SqlHelper.GetRow<Result>(update, dal);
        }
        public static Result UpdateOutRow<T, Result>(string tableName, IDAL dal, T data, SqlEventPrefix prefix, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ClassStructure res = ClassStructureCache.GetStructure(typeof(Result));
            ISqlBasic update = new SqlUpdateOut(tableName, SqlConfig.SetLockType, obj, data, res, prefix, where);
            return SqlHelper.GetRow<Result>(update, dal);
        }

        public static Result UpdateOutScalar<T, Result>(string tableName, IDAL dal, T data, string column, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic update = new SqlUpdateOut(tableName, SqlConfig.SetLockType, obj, data, column, SqlEventPrefix.deleted, where);
            return SqlHelper.ExecuteScalar<Result>(update, dal);
        }

        public static Result UpdateOutScalar<T, Result>(string tableName, IDAL dal, T data, string column, SqlEventPrefix prefix, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic update = new SqlUpdateOut(tableName, SqlConfig.SetLockType, obj, data, column, prefix, where);
            return SqlHelper.ExecuteScalar<Result>(update, dal);
        }

        public static Result[] Update<Result>(string tableName, IDAL dal, ISqlSetColumn[] columns, SqlEventPrefix prefix, params ISqlWhere[] where)
        {
            ClassStructure res = ClassStructureCache.GetStructure(typeof(Result));
            ISqlBasic update = new SqlUpdateOut(tableName, SqlConfig.SetLockType, columns, res, prefix, where);
            return SqlHelper.GetTable<Result>(update, dal);
        }
        public static Result[] Update<Result>(string tableName, IDAL dal, ISqlSetColumn[] columns, params ISqlWhere[] where)
        {
            ClassStructure res = ClassStructureCache.GetStructure(typeof(Result));
            ISqlBasic update = new SqlUpdateOut(tableName, SqlConfig.SetLockType, columns, res, where);
            return SqlHelper.GetTable<Result>(update, dal);
        }

        public static Result[] Update<Result>(string tableName, IDAL dal, ISqlSetColumn[] columns, string column, SqlEventPrefix prefix, params ISqlWhere[] where)
        {
            ISqlBasic update = new SqlUpdateOut(tableName, SqlConfig.SetLockType, columns, column, prefix, where);
            return SqlHelper.GetTable<Result>(update, dal);
        }

        public static Result[] Update<T, Result>(string tableName, IDAL dal, T data, SqlEventPrefix prefix, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ClassStructure res = ClassStructureCache.GetStructure(typeof(Result));
            ISqlBasic update = new SqlUpdateOut(tableName, SqlConfig.SetLockType, obj, data, res, prefix, where);
            return SqlHelper.GetTable<Result>(update, dal);
        }
        public static Result[] Update<T, Result>(string tableName, IDAL dal, T data, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ClassStructure res = ClassStructureCache.GetStructure(typeof(Result));
            ISqlBasic update = new SqlUpdateOut(tableName, SqlConfig.SetLockType, obj, data, res, where);
            return SqlHelper.GetTable<Result>(update, dal);
        }

        public static Result[] Update<T, Result>(string tableName, IDAL dal, T data, string column, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic update = new SqlUpdateOut(tableName, SqlConfig.SetLockType, obj, data, column, SqlEventPrefix.deleted, where);
            return SqlHelper.GetTable<Result>(update, dal);
        }
        public static Result[] Update<T, Result>(string tableName, IDAL dal, T data, string column, SqlEventPrefix prefix, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic update = new SqlUpdateOut(tableName, SqlConfig.SetLockType, obj, data, column, prefix, where);
            return SqlHelper.GetTable<Result>(update, dal);
        }
        #endregion

        #region 批量查询
        public static IBatchQuery BatchQuery(string tableName, IDAL dal, int row, int col)
        {
            if (row > SqlConfig.TempTableLimitNum || (row * col) > SqlConfig.MxColumnNum)
            {
                return new TempTableQuery(tableName, SqlConfig.QueryLockType, dal);
            }
            return new BatchQuery(tableName, SqlConfig.QueryLockType, dal);
        }
        #endregion


        #region 分页查询
        public static T[] Query<T>(string tableName, IDAL dal, string orderBy, int index, int size, out long count, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic query = new SqlPagingQuery(tableName, SqlConfig.QueryLockType, index, size, obj, orderBy, false, where);
            return SqlHelper.Query<T>(query, dal, out count);
        }
        public static T[] Query<T>(string tableName, IDAL dal, string column, string orderBy, int index, int size, out long count, params ISqlWhere[] where)
        {
            ISqlBasic query = new SqlPagingQuery(tableName, SqlConfig.QueryLockType, index, size, column, orderBy, false, where);
            return SqlHelper.Query<T>(query, dal, out count);
        }

        public static T[] Query<T>(string tableName, IDAL dal, string column, string orderBy, int index, int size, params ISqlWhere[] where)
        {
            ISqlBasic query = new SqlPagingQuery(tableName, SqlConfig.QueryLockType, index, size, column, orderBy, true, where);
            return SqlHelper.GetTable<T>(query, dal);
        }
        public static T[] Query<T>(string tableName, IDAL dal, string orderBy, int index, int size, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic query = new SqlPagingQuery(tableName, SqlConfig.QueryLockType, index, size, obj, orderBy, true, where);
            return SqlHelper.GetTable<T>(query, dal);
        }
        #endregion

        #region 查询列表
        private static ISqlWhere[] _GetSqlWhere(ISqlWhere where, ISqlWhere[] param)
        {
            if (!param.IsNull())
            {
                return param.Add(where);
            }
            else
            {
                return new ISqlWhere[]
                {
                                     where
                };
            }
        }
        public static Result[] GetOutColumn<T, Result>(string tableName, IDAL dal, string column, T[] ids, string showCol, params ISqlWhere[] param)
        {
            if (ids.Length == 1)
            {
                param = _GetSqlWhere(new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(T))) { Value = ids[0] }, param);
                return GetOutColumn<Result>(tableName, dal, showCol, param);
            }
            else if (ids.Length <= SqlConfig.InMaxNum)
            {
                param = _GetSqlWhere(new InSqlWhere<T>(column, SqlToolsHelper.GetSqlDbType(typeof(T)), ids), param);
                return GetOutColumn<Result>(tableName, dal, showCol, param);
            }
            else
            {
                using (IBatchQuery query = BatchQuery(tableName, dal, ids.Length, 1))
                {
                    query.Column = new SqlTableColumn[]
                    {
                                                new SqlTableColumn(column,SqlToolsHelper.GetSqlDbType(typeof(T)))
                    };
                    ids.ForEach(a => query.AddRow(new object[] { a }));
                    return query.Query<Result>(showCol, param);
                }
            }
        }
        public static Result[] Get<T, Result>(string tableName, IDAL dal, string column, T[] ids, params ISqlWhere[] param)
        {
            if (ids.Length == 1)
            {
                param = _GetSqlWhere(new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(T))) { Value = ids[0] }, param);
                return Get<Result>(tableName, dal, param);
            }
            else if (ids.Length <= SqlConfig.InMaxNum)
            {
                param = _GetSqlWhere(new InSqlWhere<T>(column, SqlToolsHelper.GetSqlDbType(typeof(T)), ids), param);
                return Get<Result>(tableName, dal, param);
            }
            else
            {
                using (IBatchQuery query = BatchQuery(tableName, dal, ids.Length, 1))
                {
                    query.Column = new SqlTableColumn[]
                    {
                                                new SqlTableColumn(column,SqlToolsHelper.GetSqlDbType(typeof(T)))
                    };
                    ids.ForEach(a => query.AddRow(new object[] { a }));
                    return query.Query<Result>(param);
                }
            }
        }


        public static Result[] Get<T, Result>(string tableName, IDAL dal, string column, T data, params ISqlWhere[] param)
        {
            param = _GetSqlWhere(new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(T))) { Value = data }, param);
            return Get<Result>(tableName, dal, param);
        }

        public static T[] Get<T>(string tableName, IDAL dal, params ISqlWhere[] where)
        {
            return Get<T>(tableName, dal, null, where);
        }
        public static T[] Get<T>(string tableName, IDAL dal, string orderBy, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic query = new SqlQuery(tableName, SqlConfig.QueryLockType, obj, orderBy, where);
            return SqlHelper.GetTable<T>(query, dal);
        }
        public static Result[] GetOutColumn<T, Result>(string tableName, IDAL dal, string resCol, string column, T data, params ISqlWhere[] param)
        {
            param = _GetSqlWhere(new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(T))) { Value = data }, param);
            return GetOutColumn<Result>(tableName, dal, resCol, param);
        }
        public static T[] GetOutColumn<T>(string tableName, IDAL dal, string column, params ISqlWhere[] where)
        {
            ISqlBasic query = new SqlQuery(tableName, SqlConfig.QueryLockType, column, where);
            return SqlHelper.GetTable<T>(query, dal);
        }
        public static T[] GetOutColumn<T>(string tableName, IDAL dal, string column, string orderBy, params ISqlWhere[] where)
        {
            ISqlBasic query = new SqlQuery(tableName, SqlConfig.QueryLockType, column, orderBy, where);
            return SqlHelper.GetTable<T>(query, dal);
        }
        #endregion
        #region 链接查询
        internal static T[] UnionQuery<T>(IDAL dal, UnionQueryParam[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic[] querys = where.ConvertAll((a, i) =>
            {
                return new SqlTopQuery(SqlConfig.QueryLockType, a, PublicDataDic.Letter[i], obj);
            });
            ISqlBasic query = new SqlUnionQuery(querys);
            return SqlHelper.GetTable<T>(query, dal);
        }
        internal static T UnionRow<T>(IDAL dal, UnionQueryParam[] where, string orderFieId, bool isAsc)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic[] querys = where.ConvertAll((a, i) =>
            {
                return new SqlTopQuery(SqlConfig.QueryLockType, a, PublicDataDic.Letter[i], obj, orderFieId);
            });
            string orderBy = string.Concat(orderFieId, isAsc ? " asc" : " desc");
            ISqlBasic query = new SqlUnionRow(querys, obj.ColumnName, orderBy);
            return SqlHelper.GetRow<T>(query, dal);
        }
        internal static T[] UnionQuery<T>(IDAL dal, string column, UnionQueryParam[] where)
        {
            ISqlBasic[] querys = where.ConvertAll((a, i) =>
            {
                return new SqlTopQuery(SqlConfig.QueryLockType, a, PublicDataDic.Letter[i], column);
            });
            ISqlBasic query = new SqlUnionQuery(querys);
            return SqlHelper.GetTable<T>(query, dal);
        }

        #endregion
        #region TOP查询(select top)
        public static T[] GetTop<T>(string tableName, IDAL dal, int top, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic query = new SqlTopQuery(tableName, SqlConfig.QueryLockType, top, obj, null, where);
            return SqlHelper.GetTable<T>(query, dal);
        }
        public static T[] GetTop<T>(string tableName, IDAL dal, int top, string orderBy, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic query = new SqlTopQuery(tableName, SqlConfig.QueryLockType, top, obj, orderBy, where);
            return SqlHelper.GetTable<T>(query, dal);
        }
        public static T[] GetTop<T>(string tableName, IDAL dal, string column, int top, params ISqlWhere[] where)
        {
            ISqlBasic query = new SqlTopQuery(tableName, SqlConfig.QueryLockType, top, column, null, where);
            return SqlHelper.GetTable<T>(query, dal);
        }
        public static T[] GetTop<T>(string tableName, IDAL dal, int top, string column, string orderBy, params ISqlWhere[] where)
        {
            ISqlBasic query = new SqlTopQuery(tableName, SqlConfig.QueryLockType, top, column, orderBy, where);
            return SqlHelper.GetTable<T>(query, dal);
        }
        #endregion

        #region 查询单行(GetRow)

        public static T GetRow<T>(string tableName, IDAL dal, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic query = new SqlTopQuery(tableName, SqlConfig.QueryLockType, 1, obj, null, where);
            return SqlHelper.GetRow<T>(query, dal);
        }
        public static Result GetRow<T, Result>(string tableName, IDAL dal, string column, T value)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(Result));
            ISqlWhere where = new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(T))) { Value = value };
            ISqlBasic query = new SqlTopQuery(tableName, SqlConfig.QueryLockType, 1, obj, null, where);
            return SqlHelper.GetRow<Result>(query, dal);
        }
        public static T GetRow<T>(string tableName, IDAL dal, string orderBy, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic query = new SqlTopQuery(tableName, SqlConfig.QueryLockType, 1, obj, orderBy, where);
            return SqlHelper.GetRow<T>(query, dal);
        }
        #endregion

        #region 单列查询(ExecuteScalar)

        public static T ExecuteScalarDef<T>(string tableName, IDAL dal, string column, T def, params ISqlWhere[] where)
        {
            ISqlBasic query = new SqlScalarQuery(tableName, SqlConfig.QueryLockType, column, where);
            return SqlHelper.ExecuteScalar<T>(query, dal, def);
        }
        public static T ExecuteScalar<T>(string tableName, IDAL dal, string column, ISqlWhere[] where)
        {
            ISqlBasic query = new SqlScalarQuery(tableName, SqlConfig.QueryLockType, column, where);
            return SqlHelper.ExecuteScalar<T>(query, dal);
        }

        public static T ExecuteScalar<T, T1>(string tableName, IDAL dal, string column, string where, T1 value)
        {
            ISqlBasic query = new SqlScalarQuery(tableName, SqlConfig.QueryLockType, column, new SqlWhere(where, SqlToolsHelper.GetSqlDbType(typeof(T1))) { Value = value });
            return SqlHelper.ExecuteScalar<T>(query, dal);
        }
        public static T ExecuteScalarSort<T>(string tableName, IDAL dal, string column, string orderBy, params ISqlWhere[] where)
        {
            ISqlBasic query = new SqlScalarQuery(tableName, SqlConfig.QueryLockType, column, orderBy, null, where);
            return SqlHelper.ExecuteScalar<T>(query, dal);
        }
        public static T ExecuteScalar<T>(string tableName, IDAL dal, string column, SqlFuncType func, params ISqlWhere[] where)
        {
            ISqlBasic query = new SqlScalarQuery(tableName, SqlConfig.QueryLockType, column, func.ToString(), where);
            return SqlHelper.ExecuteScalar<T>(query, dal);
        }
        public static T ExecuteScalar<T>(string tableName, IDAL dal, string column, string func, params ISqlWhere[] where)
        {
            ISqlBasic query = new SqlScalarQuery(tableName, SqlConfig.QueryLockType, column, func, where);
            return SqlHelper.ExecuteScalar<T>(query, dal);
        }

        public static bool CheckIsExists(string tableName, IDAL dal, params ISqlWhere[] where)
        {
            ISqlBasic query = new SqlTopQuery(tableName, SqlConfig.QueryLockType, 1, where);
            return SqlHelper.ExecuteScalar(query, dal) != null;
        }
        #endregion

        #region 分组(Group by)

        public static T[] GroupOutColumn<T>(string tableName, IDAL dal, string group, params ISqlWhere[] where)
        {
            ISqlBasic sql = new SqlGroupQuery(tableName, SqlConfig.QueryLockType, group, where);
            return SqlHelper.GetTable<T>(sql, dal);
        }
        public static Result[] Group<T, Result>(string tableName, IDAL dal, string[] groups, string column, T[] ids, params ISqlWhere[] where)
        {
            if (ids.Length == 1)
            {
                return Group<Result>(tableName, dal, groups, where.Add(new SqlWhere(column, SqlToolsHelper.GetSqlDbType(typeof(T))) { Value = ids[0] }));
            }
            else if (ids.Length <= SqlConfig.InMaxNum)
            {
                return Group<Result>(tableName, dal, groups, where.Add(new InSqlWhere<T>(column, ids)));
            }
            else
            {
                using (IBatchQuery batch = BatchQuery(tableName, dal, ids.Length, 1))
                {
                    batch.Column = new SqlTableColumn[]
                    {
                                                new SqlTableColumn(column,SqlToolsHelper.GetSqlDbType(typeof(T)))
                    };
                    ids.ForEach(a => batch.AddRow(a));
                    return batch.GroupTable<Result>(groups, where);
                }
            }
        }
        public static T[] Group<T>(string tableName, IDAL dal, string[] groups, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic group = new SqlGroupQuery(tableName, SqlConfig.QueryLockType, groups, obj, null, where);
            return SqlHelper.GetTable<T>(group, dal);
        }
        public static T[] GroupQuery<T>(string tableName, IDAL dal, string[] groups, int index, int size, string orderBy, out long count, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            SqlGroupQuery group = new SqlGroupQuery(tableName, SqlConfig.QueryLockType, groups, obj, null, where);
            ISqlBasic sql = new SqlGroupPagingQuery(group, index, size, orderBy, false);
            return SqlHelper.Query<T>(sql, dal, out count);
        }
        public static T[] GroupQuery<T>(string tableName, IDAL dal, string group, int index, int size, string orderBy, out long count, params ISqlWhere[] where)
        {
            SqlGroupQuery gSql = new SqlGroupQuery(tableName, SqlConfig.QueryLockType, group, where);
            ISqlBasic sql = new SqlGroupPagingQuery(gSql, index, size, orderBy, false);
            return SqlHelper.Query<T>(sql, dal, out count);
        }
        public static T GroupOutRow<T>(string tableName, IDAL dal, string[] groups, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic group = new SqlGroupQuery(tableName, SqlConfig.QueryLockType, groups, obj, null, where);
            return SqlHelper.GetRow<T>(group, dal);
        }
        public static T[] Group<T>(string tableName, IDAL dal, string[] groups, string orderBy, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic group = new SqlGroupQuery(tableName, SqlConfig.QueryLockType, groups, obj, orderBy, where);
            return SqlHelper.GetTable<T>(group, dal);
        }

        #endregion

        #region 分组查询(Group by having)

        public static T[] GroupOutColumn<T>(string tableName, IDAL dal, string group, ISqlWhere[] having, params ISqlWhere[] where)
        {
            ISqlBasic sql = new SqlGroupQuery(tableName, SqlConfig.QueryLockType, group, where)
            {
                Having = having
            };
            return SqlHelper.GetTable<T>(sql, dal);
        }
        public static T[] Group<T>(string tableName, IDAL dal, string group, ISqlWhere[] having, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic query = new SqlGroupQuery(tableName, SqlConfig.QueryLockType, new string[] { group }, obj, null, where)
            {
                Having = having
            };
            return SqlHelper.GetTable<T>(query, dal);
        }
        public static T GroupOutRow<T>(string tableName, IDAL dal, string group, ISqlWhere[] having, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic query = new SqlGroupQuery(tableName, SqlConfig.QueryLockType, new string[] { group }, obj, null, where)
            {
                Having = having
            };
            return SqlHelper.GetRow<T>(query, dal);
        }
        public static T[] Group<T>(string tableName, IDAL dal, string group, string orderBy, ISqlWhere[] having, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic query = new SqlGroupQuery(tableName, SqlConfig.QueryLockType, new string[] { group }, obj, orderBy, where)
            {
                Having = having
            };
            return SqlHelper.GetTable<T>(query, dal);
        }
        public static T[] Group<T>(string tableName, IDAL dal, string[] groups, ISqlWhere[] having, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic group = new SqlGroupQuery(tableName, SqlConfig.QueryLockType, groups, obj, null, where)
            {
                Having = having
            };
            return SqlHelper.GetTable<T>(group, dal);
        }
        public static T[] Group<T>(string tableName, IDAL dal, string[] groups, string orderBy, ISqlWhere[] having, params ISqlWhere[] where)
        {
            ClassStructure obj = ClassStructureCache.GetStructure(typeof(T));
            ISqlBasic group = new SqlGroupQuery(tableName, SqlConfig.QueryLockType, groups, obj, orderBy, where)
            {
                Having = having
            };
            return SqlHelper.GetTable<T>(group, dal);
        }
        #endregion



        #region 执行SQL
        private static void _SyncParam(IDataParameter[] parameters, SqlBasicParameter[] param)
        {
            if (param.IsNull())
            {
                return;
            }
            parameters.ForEach((a, i) =>
            {
                if (a.Direction == ParameterDirection.Output || a.Direction == ParameterDirection.InputOutput)
                {
                    param[i].Value = a.Value;
                }
            });
        }
        public static IBatchExecSql BatchSql(IDAL dal, int row, int col)
        {
            if (row > SqlConfig.TempTableLimitNum || (row * col) > SqlConfig.MxColumnNum)
            {
                return new BatchTableExecSql(dal);
            }
            else
            {
                return new Batch.BatchExecSql(dal);
            }
        }
        public static bool ExecuteNonQuery(string sql, IDAL dal, params SqlBasicParameter[] param)
        {
            IDataParameter[] parameters = param.ConvertAll(a => a.GetParameter());
            int rowNum = SqlHelper.ExecuteNonQuery(sql, dal, parameters);
            _SyncParam(parameters, param);
            return rowNum > 0;
        }

        public static T ExecuteScalar<T>(string sql, IDAL dal, params SqlBasicParameter[] param)
        {
            IDataParameter[] parameters = param.ConvertAll(a => a.GetParameter());
            object res = dal.ExecuteScalar(sql, parameters);
            _SyncParam(parameters, param);
            return ModelHelper.GetValue<T>(res);
        }
        public static T GetRow<T>(string sql, IDAL dal, params SqlBasicParameter[] param)
        {
            IDataParameter[] parameters = param.ConvertAll(a => a.GetParameter());
            DataRow row = dal.GetDataRow(sql, parameters);
            _SyncParam(parameters, param);
            return ModelHelper.GetModelByRow<T>(row);
        }
        public static T[] GetTable<T>(string sql, IDAL dal, params SqlBasicParameter[] param)
        {
            IDataParameter[] parameters = param.ConvertAll(a => a.GetParameter());
            DataTable table = dal.GetDataTable(sql, parameters);
            _SyncParam(parameters, param);
            return ModelHelper.GetModelByTable<T>(table);
        }
        public static DataSet GetDataSet(string sql, IDAL dal, params SqlBasicParameter[] param)
        {
            IDataParameter[] parameters = param.ConvertAll(a => a.GetParameter());
            return dal.GetDataSet(sql, parameters);
        }
        #endregion
    }
}